# -*- coding: utf-8 -*-
# @author: HRUN
from lib2to3.pgen2.parse import ParseError

from rest_framework import serializers
from common.encryption_and_decryption import encrypt_field,load_key
from performance.models import server, presetting, PerformanceTask, TaskScence, TaskStep, TaskScenceStep, TaskReport


class ServerSerializer(serializers.ModelSerializer):
    system_info = serializers.SerializerMethodField()
    
    def get_system_info(self, obj):
        """获取服务器系统信息"""
        return {
            'cpu_cores': obj.cpu_cores,
            'memory_gb': obj.memory_gb,
            'server_type': obj.get_server_type_display(),
            'server_status': obj.get_server_status_display()
        }
    
    class Meta:
        model = server
        fields = '__all__'

    def encrypt(self, value):
        # 加密字段
        key = load_key()
        return encrypt_field(value,key)


    def create(self, validated_data):
        # 在保存之前加密密码
        encrypted_passwd = self.encrypt(validated_data.get('sys_user_passwd'))
        validated_data['sys_user_passwd'] = encrypted_passwd
        return super().create(validated_data)

    def update(self, instance, validated_data):
        """
        更新数据时，对密码进行加密
        """
        passwd = validated_data.get('sys_user_passwd')
        if passwd and not self.is_encrypted(passwd):
            # 如果密码是明文的，则进行加密
            encrypted_passwd = self.encrypt(passwd)
            validated_data['sys_user_passwd'] = encrypted_passwd

        return super().update(instance, validated_data)

    def is_encrypted(self, passwd):

        return len(passwd) >= 64
    def validate(self, data):
        is_update = self.instance is not None

        if data.get('default_code'):
            if is_update:
                if server.objects.filter(default_code=True).exclude(id=self.instance.id).exists():
                    raise serializers.ValidationError('只能设置一个默认服务器')
            else:
                if server.objects.filter(default_code=True).exists():
                    raise serializers.ValidationError('只能设置一个默认服务器')

        return data


class PresettingSerializer(serializers.ModelSerializer):
    master_server_name = serializers.SerializerMethodField()
    worker_server_names = serializers.SerializerMethodField()
    distributed_mode_display = serializers.SerializerMethodField()
    
    def get_master_server_name(self, obj):
        return obj.master_server.name if obj.master_server else None
    
    def get_worker_server_names(self, obj):
        return [server.name for server in obj.worker_servers.all()]
    
    def get_distributed_mode_display(self, obj):
        return obj.get_distributed_mode_display()
    
    def validate(self, data):
        # 如果选择分布式模式且选择自定义模式，需要验证主服务器和工作服务器
        if data.get('distributed_mode') == 'distributed' and data.get('resource') == '20':
            if not data.get('master_server'):
                raise serializers.ValidationError('分布式自定义模式下必须选择主服务器！')
            if not data.get('worker_servers'):
                raise serializers.ValidationError('分布式自定义模式下必须选择工作服务器！')

        return data

    class Meta:
        model = presetting
        fields = '__all__'


class PerformanceTaskSerializer(serializers.ModelSerializer):
    master_server_name = serializers.SerializerMethodField()
    worker_server_names = serializers.SerializerMethodField()
    runPattern_display = serializers.SerializerMethodField()
    status_display = serializers.SerializerMethodField()
    distributed_mode_display = serializers.SerializerMethodField()
    taskType_display = serializers.SerializerMethodField()
    
    def get_master_server_name(self, obj):
        return obj.master_server.name if obj.master_server else None
    
    def get_worker_server_names(self, obj):
        return [server.name for server in obj.worker_servers.all()]
    
    def get_runPattern_display(self, obj):
        return obj.get_runPattern_display() if obj.runPattern else '未设置'
    
    def get_status_display(self, obj):
        return obj.get_status_display() if obj.status else '未设置'
    
    def get_distributed_mode_display(self, obj):
        return obj.get_distributed_mode_display()
    
    def get_taskType_display(self, obj):
        return obj.get_taskType_display()
    
    class Meta:
        model = PerformanceTask
        fields = '__all__'



class TaskScenceSerializer(serializers.ModelSerializer):
    env = serializers.SerializerMethodField()

    class Meta:
        model = TaskScence
        fields = '__all__'

    def get_env(self, obj):
        env_data = obj.env.all()
        if env_data:
            return [env.id for env in env_data][0]
        return None


class ScenceStepSerializer(serializers.ModelSerializer):
    protocol_display = serializers.SerializerMethodField()
    type_display = serializers.SerializerMethodField()
    
    def get_protocol_display(self, obj):
        return obj.get_protocol_display()
    
    def get_type_display(self, obj):
        return obj.get_type_display()
    
    class Meta:
        model = TaskStep
        fields = '__all__'


class TaskScenceStepSerializer(serializers.ModelSerializer):
    children = serializers.SerializerMethodField()
    stepInfo = serializers.SerializerMethodField(method_name='get_step_info')

    def get_step_info(self, obj):
        if obj.step:
            return ScenceStepSerializer(obj.step, context=self.context).data
        return None

    def get_children(self, obj):
        children_data = []
        if obj.children:
            # 修改查询集以确保子节点按照 sort 字段排序
            children_query = obj.children.order_by('sort')
            # 使用相同的序列化器对子节点进行序列化
            serializer = self.__class__(children_query, many=True, context=self.context)
            children_data = serializer.data
        return children_data

    class Meta:
        model = TaskScenceStep
        fields = '__all__'


# --------------------------性能运行过程序列化------------------------------


class ControllerSerializer(serializers.ModelSerializer):
    title = serializers.CharField(source='name')
    class Meta:
        model = TaskStep
        fields = ['id', 'title', 'content', 'type', 'script', 'status', 'weight']


class PerformanceStepDataSerializer(serializers.ModelSerializer):
    """用例步骤与接口嵌套的序列化器"""

    children = serializers.SerializerMethodField()
    stepInfo = serializers.SerializerMethodField(method_name='get_step_info')

    def get_step_info(self, obj):
        if obj.step:
            return ControllerSerializer(obj.step, context=self.context).data
        return None
    def get_children(self, obj):
        children_data = []
        if obj.children:
            # 修改查询集以确保子节点按照 sort 字段排序
            children_query = obj.children.order_by('sort')
            # 使用相同的序列化器对子节点进行序列化
            serializer = self.__class__(children_query, many=True, context=self.context)
            children_data = serializer.data
        return children_data

    class Meta:
        model = TaskScenceStep
        fields = '__all__'


class PerformanceScenceDataSerializer(serializers.ModelSerializer):
    """测试用例嵌套用例步骤运行序列化器"""
    taskscencestep_set = PerformanceStepDataSerializer(many=True)

    def filter_steps_status(self,step_data):
        # 如果当前节点的status为False，则直接过滤掉当前节点及其所有子节点
        if not step_data['status']:
            return False

        # 如果有子节点，则递归检查子节点
        if step_data.get('children'):
            filtered_children = []
            # 遍历子节点
            for child_step in step_data['children']:
                # 递归检查子节点
                if self.filter_steps_status(child_step):
                    # 如果子节点的status为True，则将其加入过滤后的子节点列表
                    filtered_children.append(child_step)

            # 更新当前节点的子节点列表为过滤后的子节点列表
            step_data['children'] = filtered_children

        # 返回当前节点是否保留的状态
        return step_data['status'] or bool(step_data.get('children'))

    def to_representation(self, instance):
        # 调用父类的 to_representation 方法获取 TestCase 的序列化数据
        representation = super().to_representation(instance)

        # 获取用例步骤数据
        steps_data = representation['taskscencestep_set']

        # 过滤掉 status 为 False 的数据及其子节点
        filtered_steps_data = [step_data for step_data in steps_data if
                               self.filter_steps_status(step_data.get('stepInfo')) and not step_data.get('parent')]

        if not filtered_steps_data:
            raise ParseError("没有启用的用例步骤数据")

        representation['taskscencestep_set'] = filtered_steps_data
        return representation

    class Meta:
        model = TaskScence
        fields = ['id', 'name', 'env', 'weight', 'taskscencestep_set']



class PerformanceTaskRunSerializer(serializers.ModelSerializer):
    taskScence = PerformanceScenceDataSerializer(many=True)
    presetting = PresettingSerializer()

    class Meta:
        model = PerformanceTask
        fields = ['id', 'project','taskName','taskScence', 'presetting']


# ----------------------------- TaskReport 相关序列化器 -----------------------------

class TaskReportSerializer(serializers.ModelSerializer):
    """性能测试报告序列化器"""
    taskName = serializers.CharField(source='task.taskName', read_only=True)
    taskType = serializers.CharField(source='task.taskType', read_only=True)
    pressureMode = serializers.CharField(source='task.presetting.pressureMode', read_only=True)
    envName = serializers.CharField(source='env.name', read_only=True)
    
    class Meta:
        model = TaskReport
        fields = '__all__'
        read_only_fields = ('task', 'env', 'executor')


class TaskReportCreateSerializer(serializers.ModelSerializer):
    """创建性能测试报告的序列化器"""
    
    class Meta:
        model = TaskReport
        fields = [
            'task', 'reportName', 'desc', 'reportStatus', 'env', 'executor',
            'avgTps', 'avgCpu', 'avgMemory', 'maxTps', 'minTps',
            'avgResponseTime', 'maxResponseTime', 'minResponseTime',
            'p50ResponseTime', 'p90ResponseTime', 'p95ResponseTime', 'p99ResponseTime',
            'totalRequests', 'successRequests', 'failedRequests', 'errorRate',
            'maxUsers', 'avgUsers', 'startTime', 'endTime', 'duration',
            'reportResult', 'resultAnalyse'
        ]


class TaskReportListSerializer(serializers.ModelSerializer):
    """报告列表序列化器，用于列表页面"""
    taskName = serializers.CharField(source='task.taskName', read_only=True)
    taskType = serializers.CharField(source='task.taskType', read_only=True)
    taskId = serializers.IntegerField(source='task.id', read_only=True)
    taskMode = serializers.SerializerMethodField()
    pressureMode = serializers.SerializerMethodField()
    status = serializers.CharField(source='reportStatus', read_only=True)
    start_time = serializers.DateTimeField(source='startTime', read_only=True)
    end_time = serializers.DateTimeField(source='endTime', read_only=True)
    envName = serializers.CharField(source='env.name', read_only=True)
    # 添加完整的任务对象信息
    task = serializers.SerializerMethodField()
    
    def get_task(self, obj):
        """获取完整的任务信息"""

        if obj.task:
            return {
                'id': obj.task.id,
                'taskName': obj.task.taskName,
                'taskType': obj.task.taskType,
                'distributed_mode': obj.task.distributed_mode,
                'desc': obj.task.desc,
                'create_time': obj.task.create_time.isoformat() if obj.task.create_time else None,
                'creator': obj.task.creator,
                'pressureMode': obj.task.presetting.pressureMode if obj.task.presetting else None,
            }
        return None
    
    def get_taskMode(self, obj):
        """获取任务模式"""
        task_type_map = {'10': '普通任务', '20': '定时任务'}
        return task_type_map.get(obj.task.taskType, obj.task.taskType) if obj.task else '未知'
    
    def get_pressureMode(self, obj):
        """获取压测模式"""
        try:
            pressure_mode_map = {'10': '并发模式', '20': '阶梯模式'}
            mode = obj.task.presetting.pressureMode if obj.task and obj.task.presetting else None
            return pressure_mode_map.get(mode, mode)
        except:
            return '未知'

    class Meta:
        model = TaskReport
        fields = [
            'id', 'reportName', 'status', 'taskName', 'taskId', 'taskMode', 'pressureMode',
            'avgTps', 'avgCpu', 'avgMemory', 'start_time', 'end_time', 'executor',
            'create_time', 'update_time', 'taskType', 'task', 'env', 'reportStatus',
            'totalRequests', 'successRequests', 'failedRequests', 'avgResponseTime',
            'maxResponseTime', 'minResponseTime', 'p90ResponseTime', 'p95ResponseTime',
            'p99ResponseTime', 'errorRate', 'duration','envName'
        ]


class TaskReportDetailSerializer(serializers.ModelSerializer):
    """报告详情序列化器"""
    taskName = serializers.CharField(source='task.taskName', read_only=True)
    taskType = serializers.CharField(source='task.taskType', read_only=True)
    envName = serializers.CharField(source='env.name', read_only=True)
    pressureConfig = serializers.SerializerMethodField()
    task = PerformanceTaskSerializer(read_only=True)  # 添加完整的task对象
    gui_url = serializers.SerializerMethodField()
    
    def get_pressureConfig(self, obj):
        """获取压测配置"""
        import json
        try:
            if obj.task.presetting:
                return {
                    'pressureMode': obj.task.presetting.pressureMode,
                    'pressureConfig': obj.task.presetting.pressureConfig,
                    'timeUnit': obj.task.presetting.timeUnit,
                }
            return None
        except:
            return None
    def get_gui_url(self, obj):
        """从 reportResult 字段中解析 gui_url """
        import json
        if obj.reportResult:
            try:
                data = json.loads(obj.reportResult)
                return data.get('gui_url')
            except Exception:
                return None
        return None

    class Meta:
        model = TaskReport
        fields = '__all__'


